home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / utility / sml-mode-3.3b / sml-mosml.el < prev    next >
Encoding:
Text File  |  1997-08-18  |  7.6 KB  |  198 lines  |  [TEXT/R*ch]

  1. ;;; sml-mosml.el: Modifies inferior-sml-mode defaults for Moscow ML.
  2.  
  3. ;; Copyright (C) 1997, Matthew J. Morley
  4.  
  5. ;; $Revision: 1.5 $
  6. ;; $Date: 1997/06/23 09:19:56 $
  7.  
  8. ;; This file is not part of GNU Emacs, but it is distributed under the
  9. ;; same conditions.
  10.  
  11. ;; ====================================================================
  12.  
  13. ;; This program is free software; you can redistribute it and/or
  14. ;; modify it under the terms of the GNU General Public License as
  15. ;; published by the Free Software Foundation; either version 2, or (at
  16. ;; your option) any later version.
  17.  
  18. ;; This program is distributed in the hope that it will be useful, but
  19. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  20. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21. ;; General Public License for more details.
  22.  
  23. ;; You should have received a copy of the GNU General Public License
  24. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  25. ;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  
  27. ;; ====================================================================
  28.  
  29. ;;; DESCRIPTION
  30.  
  31. ;; To use this library just put
  32.  
  33. ;;(autoload 'sml-mosml "sml-mosml" "Set up and run Moscow ML." t)
  34.  
  35. ;; in your .emacs file. If you only ever use Moscow ML then you might
  36. ;; as well put something like
  37.  
  38. ;;(setq sml-mode-hook
  39. ;;      '(lambda() "SML mode defaults to Moscow ML"
  40. ;;     (define-key  sml-mode-map "\C-cp" 'sml-mosml)))
  41.  
  42. ;; for your sml-mode-hook. The command prompts for the program name 
  43. ;; and any command line options. 
  44.  
  45. ;; If you need to reset the default value of sml-program-name, or any
  46. ;; of the other compiler variables, put something like
  47.  
  48. ;;(eval-after-load "sml-mosml" '(setq sml-program-name "whatever"))
  49.  
  50. ;; in your .emacs -- or you can use the inferior-sml-{load,mode}-hooks
  51. ;; to achieve the same ends.
  52.  
  53. ;;; CODE
  54.  
  55. (require 'sml-proc)
  56.  
  57. ;; The regular expression used when looking for errors. Moscow ML errors:
  58.  
  59. (defconst sml-mosml-error-regexp
  60.   (concat "^File \"\\([^\"]+\\)\","                    ;1
  61.           " line \\([0-9]+\\)-?\\([0-9]+\\)?,"         ;2-3?
  62.           " characters \\([0-9]+\\)-\\([0-9]+\\):")    ;4-5
  63.   "Default regexp matching Moscow ML error messages.
  64. If you change this significantly you may also need to redefine 
  65. `sml-mosml-error-parser' (qv).")
  66.  
  67. ;; File "puzz.ml", line 30-31, characters 10-70:
  68. ;; ! ..........first 0 l = []
  69. ;; !         | first n (h::t) = h::(first (n-1) t)
  70. ;; ! Warning: pattern matching is not exhaustive
  71.  
  72. ;; ! Toplevel input:
  73. ;; ditto
  74.  
  75. (defconst sml-mosml-error-messages
  76.   (concat "^! \\("
  77.           (mapconcat 'identity
  78.                      (list "\\(Warning: .*\\)"
  79.                            "\\(Type clash\\):"
  80.                            "\\(Ill-formed infix expression\\)"
  81.                            "\\(Syntax error.*\\)")
  82.                      "\\|")
  83.           "\\).*$")
  84.   "RE to match Moscow ML type-of-error reports. This regular expression
  85. must follow the whole line pattern \"^! \\\\(%s\\\\).*$\", and the %s 
  86. stands for a \"\\\\|\" separated list of regular expressions each of
  87. which must, I repeat *must*, contain at least one \"\\\\(%s\\\\)\" group.
  88. The %s regexp in the first such group will be the actual error report
  89. echoed to the user.")
  90.  
  91. (defun sml-mosml-error-parser (pt)
  92.  "This function looks for the next Moscow ML error message following PT
  93. and parses an error message into a list
  94.   \(file start-line start-col end-of-err msg\)
  95. where
  96.  
  97.   FILE is the file in which the error occurs
  98.  
  99.   START-LINE is the line number in the file where the error occurs
  100.  
  101.   START-COL is the character position on START-LINE where the error occurs
  102.  
  103.   END-OF-ERR is an Emacs Lisp expression that when evaluated at
  104.   \(start-line,start-col\) moves point to the end of the errorful text
  105.  
  106.   MSG is the text of the error message given by the compiler, if such text
  107.   can be found.
  108.  
  109. The first three are mandatory return values for `sml-next-error'. 
  110. See also `sml-error-parser'."
  111.  (save-excursion
  112.    (goto-char pt)
  113.    (if (not (looking-at sml-mosml-error-regexp))
  114.        ;; the user loses big time.
  115.        (list nil nil nil)
  116.      (let* ((file (match-string 1))                  ; the file
  117.             (slin (string-to-int (match-string 2)))  ; the start line
  118.             ;; char range is (n,m], 0 is column 1 of slin
  119.             (scol (string-to-int (match-string 4)))  ; the start col
  120.             ;; get to the end by doing "forward-char m - n"
  121.             (eoe `(forward-char ,(- (string-to-int (match-string 5)) scol)))
  122.             (msg))
  123.        ;; look for the error message at end of the chunk of "! " lines
  124.        (forward-line 1)
  125.        (while (and (looking-at "^! ")
  126.                    (not (looking-at sml-mosml-error-messages)))
  127.          (forward-line 1))
  128.        ;; found one if match-beginning 1 is non-nil.
  129.        (if (match-beginning 1)
  130.            (progn 
  131.              (setq msg (match-string 1))
  132.              ;; refine since m-begin 1 implies m-begin N for some N>1 as
  133.              ;; long as sml-mosml-error-messages is sane as advertised.
  134.              ;; match-data is a list N+1 of pairs, consecutive elts being
  135.              ;; beg and end markers for the \( \) in the match. 0 is the
  136.              ;; whole match.
  137.              (let ((matches (1- (/ (length (match-data)) 2))) ; ignore 0th
  138.                    (group 2))                                 ; & ignore 1st
  139.                (while (and (not (match-beginning group))
  140.                            (<= group matches))
  141.                  (setq group (1+ group)))
  142.                (if (<= group matches)
  143.                    (setq msg (match-string group))))))
  144.        ;; 1+ scol because char 0 means column 1 of slin.
  145.        (nconc (list file slin (1+ scol)) (list eoe) (list msg))))))
  146.  
  147. ;;;###autoload
  148. (defun sml-mosml (pfx)
  149.    "Set up and run Moscow ML.
  150. Prefix argument means accept the defaults below.
  151.  
  152. Note: defaults set here will be clobbered if you setq them in the
  153. inferior-sml-mode-hook.
  154.  
  155.  sml-program-name  <option> \(default \"mosml\"\)
  156.  sml-default-arg   <option> \(default \"\"\)
  157.  sml-use-command   \"use \\\"%s\\\"\"
  158.  sml-cd-command    \"load \"FileSys\"; FileSys.chDir \\\"%s\\\"\"
  159.  sml-prompt-regexp \"^- *\"
  160.  sml-error-regexp  sml-mosml-error-regexp
  161.  sml-error-parser  'sml-mosml-error-parser"
  162.    (interactive "P")
  163.    (let ((cmd (if pfx "mosml"
  164.                 (read-string "Command name: " sml-program-name)))
  165.          (arg (if pfx ""
  166.                 (read-string "Any arguments or options (default none): " ""))))
  167.      ;; sml-mode global variables
  168.      (setq sml-program-name cmd)
  169.      (setq sml-default-arg  arg)
  170.      ;; buffer-local (compiler-local) variables
  171.      (setq-default sml-use-command   "use \"%s\""
  172.                    sml-cd-command    "load \"FileSys\"; FileSys.chDir \"%s\""
  173.                    sml-prompt-regexp "^- *"
  174.                    sml-error-regexp  sml-mosml-error-regexp
  175.                    sml-error-parser  'sml-mosml-error-parser)
  176.      (sml-run cmd sml-default-arg)))
  177.  
  178. ;;; Do the default setup on loading this file.
  179.  
  180. ;; setqing these two may override user's hooked defaults. users
  181. ;; therefore need load this file before setting sml-program-name or
  182. ;; sml-default-arg in their inferior-sml-load-hook. sorry.
  183.  
  184. (setq         sml-program-name  "mosml"
  185.               sml-default-arg   "")
  186.  
  187. ;; same sort of problem here too: users should to setq-default these
  188. ;; after this file is loaded, on inferior-sml-load-hook. as these are
  189. ;; buffer-local, users can instead set them on inferior-sml-mode-hook.
  190.  
  191. (setq-default sml-use-command   "use \"%s\""
  192.               sml-cd-command    "load \"FileSys\"; FileSys.chDir \"%s\""
  193.               sml-prompt-regexp "^- *"
  194.               sml-error-regexp  sml-mosml-error-regexp
  195.               sml-error-parser  'sml-mosml-error-parser)
  196.  
  197. ;;; sml-mosml.el endeded
  198.